<?php

/**
 * Created by PhpStorm.
 * User: mrjnamei
 * Date: 17-5-12
 * Time: 上午10:35
 */

namespace App\Winged\Auth\Backend\Api;

use App\Winged\Auth\Controllers\AuthController;
use App\Winged\Backend\Http\WingedHttp;
use App\Winged\Middleware\ErrorResponseMiddle;
use App\Winged\SessionUser;
use Encore\Admin\Facades\Admin;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;

class Api
{
    /**
     * @var 各自的模块需要定义好自己的模块的名称，ｕｒｌ前缀
     */
    protected static $module;

    /**
     * @var array　请求的地址集合，
     */
    public static $actions = [];

    /**
     * 有些接口不需要token就能访问的，这里区别开来。
     *
     * @var bool
     */
    public static $needToken = true;

    /**
     * 成功的状态
     */
    const SUCCESS = 'SUCCESS';

    const FAIL = 'FAIL';

    public static $headers = [];


    /**
     * 组织请求url格式
     *
     * @param $path
     *
     * @return string
     * @throws \Exception
     */
    public static function getPath($path)
    {
        if (!array_key_exists($path, static::$actions)) {
            throw new \Exception('请求接口不存在:' . $path);
        }
        $ds   = '/';
        $path = trim(static::$actions[$path], $ds);
        return static::$module . $ds . $path;
    }

    /**
     * get 请求数据
     *
     * @return Collection|string
     * @throws \Exception
     */
    public static function doGet()
    {
        $args = func_get_args();
        $path = array_shift($args);
        if (count($args) === 0) {
            list($status, $content) = app()->http->request(static::getPath($path), 'GET', null, self::getHeader());
        } else {
            list($status, $content) = app()->http->request(vsprintf(static::getPath($path), $args), 'GET', null, self::getHeader());
        }
        self::handleStatus($status ,$content);
        return self::handleResponse($content);
    }

    /**
     * @param      $path
     * @param      $body
     * @param bool $sign
     *
     * @return \Illuminate\Support\Collection|string
     * @throws \Exception
     */
    public static function doPost($path, $body)
    {
        list($status, $content) = app()->http->request(static::getPath($path), 'POST', $body, self::getHeader());
        self::handleStatus($status ,$content);
        return self::handleResponse($content);
    }

    /**
     * @param      $path
     * @param      $body
     * @param bool $sign
     *
     * @return \Illuminate\Support\Collection|string
     * @throws \Exception
     */
    public static function doPut($path, $body)
    {
        list($status, $content) = app()->http->request(static::getPath($path), 'PUT', $body, self::getHeader());
        self::handleStatus($status ,$content);
        return self::handleResponse($content);
    }

    /**
     * delete
     */
    public static function doDelete($path)
    {
        $args = func_get_args();
        $path = array_shift($args);
        if (count($args) === 0) {
            list($status, $content) = app()->http->request(static::getPath($path), 'DELETE', null, self::getHeader());
        } else {
            list($status, $content) = app()->http->request(vsprintf(static::getPath($path), $args), 'DELETE', null, self::getHeader());
        }
        self::handleStatus($status ,$content);
        return self::handleResponse($content);
    }


    /**
     * 处理请求错误
     *
     * @param $status
     */
    public static function handleStatus($status ,$content = '')
    {
        switch ($status) {
            case ($status >= 200 && $status < 300 ) :
                $message = true;
                break;
            case 401 :
                if(!Auth::guest()){
                    Auth::logout() ;
                    $message = '您的登录信息已失效，请重新登录';
                }else{
                    $message = '账号密码错误';
                }
                break;
            case 403 :
                $message = '禁止访问';
                break;
            case 404 :
                $message = '404 not found!';
                break;
            case 500 :
                $message = '服务器错误';
                break;
            default :
                $message = '网络错误' . $status;
        }
        if (true === $message) {
            return;
        } else {
            if (request()->wantsJson()) {
                $errmsg = response()->json([
                    'status'  => $status,
                    'message' => $message,
                    'content' => $content,
                ],$status);
                ErrorResponseMiddle::respond($errmsg);
            } else {
                if($status == 401 && !request()->is('admin/auth/login')){
                    // 在这里调用Auth::logout()　无法正常退出。一定要清空ｓｅｓｓｉｏｎ。
                    request()->session()->flush();
                    request()->session()->save();
                    $errmsg = redirect("/");
                    ErrorResponseMiddle::respond($errmsg);
                }elseif($status != 401){
                    abort($status,$message);
                }else{
                    throw new \Exception(
                        $message
                    );
                }
            }
        }
    }

    /**
     * 处理逻辑错误
     */
    public static function handleLogicError($content)
    {
        if (request()->wantsJson()) {
            $errmsg = response()->json([
                'status'  => -1,
                'message' => $content['status'],
            ]);
        } else {
            if (Auth::guest()) {
                return;
            }
            $errmsg = response(Admin::content()->withError($content['status']));
        }
        ErrorResponseMiddle::respond($errmsg);
    }

    /**
     * 处理响应
     */
    public static function handleResponse($content)
    {
        try {
            $data = \GuzzleHttp\json_decode($content, TRUE);
            return new Collection($data);
        } catch (\InvalidArgumentException $e) {
            return $content;
        }

    }

    /**
     * 获取请求头
     * access_token
     * tenant_id
     */
    public static function getHeader()
    {
        return array_merge(['tenant_id' => tenant(), 'PLATFORM' => '0','ACCESS_TOKEN' => 'x'], static::$needToken ? ['Authorization' => "Bearer " . token()] : [], static::$headers);
    }

    /**
     * 获取本身实例
     *
     * @return static
     */
    public static function instance()
    {
        return new static();
    }


    /**
     * 格式化响应
     * 控制器按需使用 . 自己捕获异常
     * ['status' => 'success' ] // 带有这种的，直接返回可直接使用的变量，
     * 否则抛出异常
     */
    public static function formatResponse($data)
    {
        if (is_string($data)) {
            $data = json_decode($data, true);
        }
        if (!isset($data ['status'])) {
            if (is_array($data)) {
                $data = json_encode($data);
            }
            throw new ServerErrorException("服务器响应失败:" . $data);
        }
        if ($data ['status'] !== self::SUCCESS) {
            throw new LogicException("操作失败:" . $data['error_code']?? $data['status']);
        }
        return $data;
    }

    /**
     * 针对中转接口
     */
    public static function doTransfer($path, $method, $params = null)
    {
        list($status, $content) = app()->http->request($path, $method, $params, self::getHeader());
        self::handleStatus($status ,$content);
        return [$status, $content];
    }

       public static function doUpload($path, $params)
    {
        $headers = self::getHeader();
        list($status, $content) = app()->http->request($path, WingedHttp::POST, $params, $headers);
        self::handleStatus($status ,$content);
        return [$status, $content];
    }

}

